/*
 * shared_buffers_mgr.hxx
 *
 *  Created on: 2023年8月30日
 *      Author: Dylan.Gao
 */

#ifndef _TEST_SHARED_BUFFER_MGR_HXX_
#define _TEST_SHARED_BUFFER_MGR_HXX_

#include <cxxtest/TestSuite.h>
#include <dm/os/shared_buffer_mgr.hpp>

class CTestOsSharedBuffersMgr:public CxxTest::TestSuite{
public:
    typedef int record_t;
    typedef dm::int64 id_t;
    typedef dm::uint8 mask_t;
    enum{
        SizeOfMasks = 2
    };

    typedef dm::os::TCSharedBufferMgr<record_t,id_t,mask_t,SizeOfMasks> mgr_t;

	class CLoader:public mgr_t::CLoader{
	public:
		CLoader():m_idx(-1),m_maxIdx(-1){
		}

		bool addALoaded( int& record ){
			if( record>m_maxIdx )
				m_maxIdx = record;

			return true;
		}

		bool filterLoaded(){
			m_idx = m_maxIdx;
			return true;
		}

		bool next(){
			++m_idx;
            if( m_idx>=42 )	// 创建42条记录,每个缓冲区2*8=16个记录。创建3个缓冲区
				return false;
			return true;
		}

		bool loadRecord( int& r ){
			r = m_idx;
			return true;
		}

		int m_maxIdx;
		int m_idx;
	};

    class CFinder:public mgr_t::CFinder{
    public:
        bool compareId(record_t& record,const id_t& id){
            return record==id;
        }
    };

    void testReset(){
		mgr_t::CUnloader unloader;

        mgr_t mgr("testBuffer1");
        mgr.remove(unloader);
    }

	void testDefault(){
		CLoader loader;

        mgr_t mgr("testBuffer1");

        TSM_ASSERT_EQUALS("记录数",mgr.count(),0);

        TSM_ASSERT("加载记录",mgr.loadNews(loader));

		TSM_ASSERT("加载无记录",!mgr.loadNew(loader));

        TSM_ASSERT_EQUALS("记录数",mgr.count(),42);

        mgr_t::CPos pos;
        mgr_t::CNormalReader reader;
        int v;

        TSM_ASSERT("首记录",mgr.first(pos, &v, &reader));
        for( int i=0;i<41;++i ){
        	TSM_ASSERT_EQUALS("记录",i,v);
        	TSM_ASSERT("下一记录",(pos=mgr.next(pos, &v, &reader)).isValid());
        }

        TSM_ASSERT("尾记录",pos = mgr.last( &v, &reader));
        for( int i=41;i>=1;--i ){
        	TSM_ASSERT_EQUALS("记录",i,v);
        	TSM_ASSERT("上一记录",pos = mgr.previous(pos, &v, &reader));
        }
    }

    void testFirstLast(){
        mgr_t::CNormalReader reader;
		int value;
        mgr_t::CPos pos;
        mgr_t mgr("testBuffer1");

        TSM_ASSERT("获取第一条记录",(pos = mgr.first(&value, &reader)).isValid());

		TSM_ASSERT_EQUALS("第一条记录",pos.getBufferIndex(),0);
		TSM_ASSERT_EQUALS("第一条记录",pos.getBufferOffset(),0);
		TSM_ASSERT_EQUALS("第一条记录",value,0);

        TSM_ASSERT("获取第一条记录",(pos = mgr.next(pos,&value, &reader)).isValid());

        TSM_ASSERT_EQUALS("第一条记录",pos.getBufferIndex(),0);
        TSM_ASSERT_EQUALS("第一条记录",pos.getBufferOffset(),1);
        TSM_ASSERT_EQUALS("第一条记录",value,1);

        TSM_ASSERT("最后记录",pos = mgr.last(&value, &reader));
		TSM_ASSERT_EQUALS("最后记录缓冲区",pos.getBufferIndex(),2);
		TSM_ASSERT_EQUALS("最后记录",pos.getBufferOffset(),9);
		TSM_ASSERT_EQUALS("最后记录",value,41);
    }

    void testPos(){
        mgr_t mgr("testBuffer1");
        mgr_t::CPos pos;

        pos = mgr.pos(0,30);
        TSM_ASSERT_EQUALS("构造pos",pos.isValid(),false);

        pos = mgr.pos(1,3);
        TSM_ASSERT_EQUALS("构造pos",pos.isValid(),true);
    }

    void testFind(){
        mgr_t mgr("testBuffer1");
        mgr_t::CPos pos;
        CFinder finder;

        id_t id = 1;
        TSM_ASSERT_EQUALS("查找id",mgr.find(id,finder,pos),true);

		TSM_ASSERT_EQUALS("查找pos",pos.getBufferIndex(),0);
		TSM_ASSERT_EQUALS("查找pos",pos.getBufferOffset(),1);

        id = 18;
        TSM_ASSERT_EQUALS("构造pos",mgr.find(id,finder,pos),true);

		TSM_ASSERT_EQUALS("查找pos",pos.getBufferIndex(),1);
		TSM_ASSERT_EQUALS("查找pos",pos.getBufferOffset(),2);
	}

	void testRemove(){
		CLoader loader;
        mgr_t mgr("testBuffer1");
		mgr_t::CUnloader unloader;
		mgr.remove(unloader);
	}
};

#endif /* _TEST_SHARED_BUFFER_MGR_HXX_ */
